package com.yunquan.ohana.ui.calendar.sync

import android.app.Application
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import androidx.databinding.ObservableArrayList
import com.google.gson.Gson
import com.yunquan.ohana.BR
import com.yunquan.ohana.R
import com.yunquan.ohana.base.binding.command.BindingAction
import com.yunquan.ohana.base.binding.command.BindingCommand
import com.yunquan.ohana.base.bus.RxBus
import com.yunquan.ohana.base.bus.event.SingleLiveEvent
import com.yunquan.ohana.base.ui.BaseViewModel
import com.yunquan.ohana.db.DBFrames
import com.yunquan.ohana.dialog.LoadingDialog
import com.yunquan.ohana.entity.EventEntity
import com.yunquan.ohana.entity.EventType
import com.yunquan.ohana.entity.FramesDataManager
import com.yunquan.ohana.entity.FramesEntity
import com.yunquan.ohana.entity.LocalFrameEntity
import com.yunquan.ohana.entity.ScheduleModelVo
import com.yunquan.ohana.http.BaseHttp
import com.yunquan.ohana.http.exception.ApiException
import com.yunquan.ohana.http.observer.BaseObserver
import com.yunquan.ohana.http.transformer.CommonTransformer
import com.yunquan.ohana.ui.calendar.sync.syncNew.SyncNewActivity
import com.yunquan.ohana.utils.ToastUtils
import io.reactivex.rxjava3.disposables.Disposable
import me.tatarka.bindingcollectionadapter2.ItemBinding
import okhttp3.RequestBody.Companion.toRequestBody

class SyncViewModel(application: Application) : BaseViewModel(application) {

    val ui = SingleLiveEvent<Int>()

    val items = ObservableArrayList<SyncItemViewModel>()
    val itemBinding = ItemBinding.of<SyncItemViewModel>(
        BR.syncItemViewModel,
        R.layout.item_sync_calendar_event
    )

    var mCurrentData: ScheduleModelVo? = null

    var mDeviceId: String? = null
    var mRoleId:String? = null

    val onSyncNewClick = BindingCommand<Any>(object : BindingAction{
        override fun call() {
            val bundle = Bundle()
            bundle.putString("deviceId", mDeviceId)
            bundle.putString("roleId", mRoleId)
            startActivity(SyncNewActivity::class.java, bundle)
        }
    })

    fun toSync(data: ScheduleModelVo) {
        mCurrentData = data
        ui.value = 0
    }


    fun bindFrames(code: String) {
        val map = mutableMapOf<String, Any>()
        map["qrcode"] = code
        val json = Gson().toJson(map)
        val body = json.toRequestBody(BaseHttp.MEDIA_TYPE_JSON)
        BaseHttp.api.bindDevice(body)
            .compose(CommonTransformer())
            .subscribe(object : BaseObserver<Boolean>() {
                override fun onSubscribe(d: Disposable) {
                    super.onSubscribe(d)
                    LoadingDialog.getInstance().show()
                }

                override fun onSuccess(result: Boolean?) {
                    super.onSuccess(result)
                    if (result == true) {
                        getFrames()
                    } else {
                        ToastUtils.showShort(R.string.bind_failed)
                        LoadingDialog.getInstance().dismiss()
                    }
                }

                override fun onError(e: ApiException) {
                    super.onError(e)
                    LoadingDialog.getInstance().dismiss()
                }
            })
    }

    fun getFrames() {
        val map = mutableMapOf<String, Any>()
        val json = Gson().toJson(map)
        val body = json.toRequestBody(BaseHttp.MEDIA_TYPE_JSON)
        BaseHttp.api.getUserDeviceList(body)
            .compose(CommonTransformer())
            .subscribe(object : BaseObserver<List<FramesEntity>>() {
                override fun onSuccess(result: List<FramesEntity>?) {
                    super.onSuccess(result)
                    if (result?.isNotEmpty() == true) {
                        FramesDataManager.instance.setData(result)
                        for (i in result.indices) {
                            val e = result[i]
                            val bean = LocalFrameEntity(
                                deviceId = e.id,
                                name = e.name,
                                location = e.roomLocation,
                                online = if (e.online!!) 1 else 0
                            )
                            DBFrames.instance.saveOrUpdate(bean)
                        }
                        Handler(Looper.getMainLooper()).postDelayed({
                            syncToDevice(result)
                        }, 500)
                        RxBus.getDefault().post(EventEntity(EventType.FRESH_DEVICE_LIST))
                    } else {
                        LoadingDialog.getInstance().dismiss()
                    }
                }

                override fun onError(e: ApiException) {
                    super.onError(e)
                    LoadingDialog.getInstance().dismiss()
                }

                override fun onComplete() {
                    super.onComplete()
                    RxBus.getDefault().post(EventEntity(EventType.UPDATE_DEVICE_LIST_COMPLETE))
                }
            })
    }

    fun syncToDevice(devices: List<FramesEntity>) {
        if (mCurrentData == null) {
            ToastUtils.showShort(R.string.synchronization_failed)
            return
        }
        val syncDeviceList = devices.filter { it.id != mDeviceId }
        if(syncDeviceList.isEmpty()){
            return
        }
        val map = mutableMapOf<String, Any>()
        map["scheduleId"] = arrayListOf(mCurrentData!!.id)
        map["deviceId"] = syncDeviceList.map { it.id }
        val body = Gson().toJson(map).toRequestBody(BaseHttp.MEDIA_TYPE_JSON)
        BaseHttp.api.addTasksDeviceRelation(body)
            .compose(CommonTransformer())
            .subscribe(object : BaseObserver<Boolean>() {
                override fun onSubscribe(d: Disposable) {
                    super.onSubscribe(d)
                    if (!LoadingDialog.getInstance().isShowing()) {
                        LoadingDialog.getInstance().show()
                    }
                }

                override fun onSuccess(result: Boolean?) {
                    super.onSuccess(result)
                    if (result == true) {
                        ToastUtils.showShort(R.string.synchronization_is_successful)
                    } else {
                        ToastUtils.showShort(R.string.synchronization_failed)
                    }
                }

                override fun onComplete() {
                    super.onComplete()
                    LoadingDialog.getInstance().dismiss()
                }
            })
    }
}